﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace MvcSimplyCleverPart2
{
    public class ZipCodeValidatorAttribute : ValidationAttribute, IClientValidatable
    {
        private readonly string dependentProperty;
        private readonly Dictionary<string, string> patterns;

        public ZipCodeValidatorAttribute(string dependentProperty)
        {
            this.dependentProperty = dependentProperty;
            this.patterns = new Dictionary<string, string> { {"US", @"^\d{5}(-(\d{4}|\d{6}))?$"} , {"CZ", @"^\d{3} ?\d{2}$"}};            
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var dependentProperty = validationContext.ObjectInstance.GetType().GetProperty(this.dependentProperty);
			var dependentPropertyValue = Convert.ToString(dependentProperty.GetValue(validationContext.ObjectInstance, null));
			
            var regex = new Regex(this.patterns[dependentPropertyValue]);
            var fieldVal = value != null ? value.ToString() : string.Empty;

            if (regex.IsMatch(fieldVal))
            {
                return ValidationResult.Success;
            }
            else
            {
                return new ValidationResult(this.ErrorMessageString);
            }
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var viewContext = (ViewContext)context;
            var dependantPropertyId = this.dependentProperty;

            var rule = new ModelClientValidationRule();
            rule.ErrorMessage = this.ErrorMessageString;
            rule.ValidationType = "zipvalidator";
            rule.ValidationParameters.Add("dependantproperty", dependantPropertyId);
            rule.ValidationParameters.Add("patterns", new JavaScriptSerializer().Serialize(this.patterns));

            yield return rule;
        }
    }
}